﻿// Copyright (c) MichaConrad. All rights reserved. See License.txt in the project root for license information.

namespace LinqToLdapExtensions
{
    using LinqToLdap;
    using LinqToLdapExtensions.Scope;

    /// <summary>
    /// <para>This contract is responsible for generating <see cref="LinqToLdap.DirectoryContext"/> instances.
    /// </para><para>
    /// Implementations should adhere to the following:
    /// <list type="number">
    /// <item><description>Each constructor must take <see cref="ScopeState"/> as one parameter to define the scope type of <see cref="IDirectoryContextFactory.CurrentDirectoryContextBinding"/>.</description></item>
    /// <item><description>
    /// The pattern of how to use this contract is:
    /// <list type="bullet">
    /// <item><description><see cref="IDirectoryContextFactory.CreateContext()"/> to factor a new <see cref="IDirectoryContext"/></description></item>
    /// <item><description>Bind() the context to <see cref="IDirectoryContextFactory.CurrentDirectoryContextBinding"/></description></item>
    /// <item><description>prior to be able to call <see cref="IDirectoryContextFactory.GetCurrentContext()"/></description></item>
    /// </list>
    /// </description></item>
    /// </list>
    /// </para>
    /// </summary>
    public interface IDirectoryContextFactory
    {
        /// <summary>
        /// Gets the current directory context.
        /// </summary>
        ICurrentDirectoryContextBinding CurrentDirectoryContextBinding { get; }

        /// <summary>
        /// Creates a new instance of <see cref="LinqToLdap.DirectoryContext" /> based on given configuration options.
        /// </summary>
        /// <returns>A new instance of <see cref="LinqToLdap.DirectoryContext" />.</returns>
        IDirectoryContext CreateContext();

        /// <summary>
        /// <para>Gets the current <see cref="IDirectoryContext"/> bound to the scope.</para>
        /// <para>This method does not create a new instance. Call <see cref="IDirectoryContextFactory.CreateContext()"/> first 
        /// and bind it to <see cref="IDirectoryContextFactory.CurrentDirectoryContextBinding"/>.
        /// </para>
        /// </summary>
        /// <returns>
        /// The <see cref="IDirectoryContext"/> instance in the current scope.
        /// </returns>
        /// <remarks>
        /// Implementations should adhere to the following:
        /// <list type="bullet">
        /// <item><description>Throw exception if no binding is defined.</description></item>
        /// </list>
        /// </remarks>
        IDirectoryContext GetCurrentContext();
    }
}
